package com.ruoyi.filemanager.command;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.filemanager.constant.ElFinderConstants;
import com.ruoyi.filemanager.core.Target;
import com.ruoyi.filemanager.service.ElfinderStorage;
import com.ruoyi.filemanager.service.VolumeHandler;
import com.ruoyi.filemanager.support.archiver.Archiver;
import com.ruoyi.filemanager.support.archiver.ArchiverType;
import com.ruoyi.filemanager.util.HttpUtil;

public class ZipdlCommand extends AbstractCommand implements ElfinderCommand
{
    @Override
    public void execute(ElfinderStorage elfinderStorage, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        JSONObject json = new JSONObject();
        final String[] targets = request.getParameterValues(ElFinderConstants.ELFINDER_PARAMETER_TARGETS);
        boolean download = request.getParameter(ElFinderConstants.ELFINDER_PARAMETER_DOWNLOAD) != null;
        if (download)
        {
            // String cwd = targets[0];
            String archiveFileTarget = targets[1];
            String downloadFileName = targets[2];
            String mime = targets[3];
            VolumeHandler archiveTarget = findTarget(elfinderStorage, archiveFileTarget);
            response.setCharacterEncoding(Constants.UTF8);
            response.setContentType(mime);
            response.setHeader("Content-Disposition", HttpUtil.safeHttpHeader("attachments; "
                    + HttpUtil.getAttachementFileName(downloadFileName, request.getHeader("USER-AGENT"))));
            response.setHeader("Content-Transfer-Encoding", "binary");

            OutputStream out = response.getOutputStream();
            response.setContentLength((int) archiveTarget.getSize());

            try (InputStream is = archiveTarget.openInputStream())
            {
                IOUtils.copy(is, out);
                out.flush();
                out.close();
            }
            finally
            {
                archiveTarget.delete();
            }

        }
        else
        {
            List<Target> targetList = findTargets(elfinderStorage, targets);
            Archiver archiver = ArchiverType.of("application/zip").getStrategy();
            Target targetArchive = archiver.compress(targetList.toArray(new Target[] {}));
            targetArchive.getVolume().getParent(targetArchive);
            json.put(ElFinderConstants.ELFINDER_PARAMETER_ZIPDL,
                    getTargetInfo(request, new VolumeHandler(targetArchive, elfinderStorage)));
            PrintWriter writer = response.getWriter();
            try
            {
                response.setContentType("application/json; charset=UTF-8");
                writer.write(json.toJSONString());
                writer.flush();
            }
            catch (Exception e)
            {
                logger.error("Unable to execute abstract json command", e);
                json.put(ElFinderConstants.ELFINDER_JSON_RESPONSE_ERROR, e.getMessage());
                writer.write(json.toJSONString());
                writer.flush();
            }
            finally
            {
                writer.close();
            }
        }
    }
}
